package com.qumitech.visualnovel.service.forbidden.impl;

import com.alibaba.fastjson.JSONObject;
import com.qumitech.visualnovel.component.exception.BusinessException;
import com.qumitech.visualnovel.component.util.CommonUtil;
import com.qumitech.visualnovel.component.util.DateUtil;
import com.qumitech.visualnovel.component.util.HttpInvokeUtil;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.ResultEnum;
import com.qumitech.visualnovel.controller.vo.forbidden.UserForbiddenAdminDTO;
import com.qumitech.visualnovel.controller.vo.forbidden.UserForbiddenVO;
import com.qumitech.visualnovel.datasource.console.AccountLoginMapper;
import com.qumitech.visualnovel.datasource.console.AccountRegisterMapper;
import com.qumitech.visualnovel.datasource.app.UserForbiddenMapper;
import com.qumitech.visualnovel.model.dao.console.UserInfo;
import com.qumitech.visualnovel.model.common.UrlConstant;
import com.qumitech.visualnovel.service.forbidden.UserForbiddenService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author :  ZhChNing
 * @Descriptiom :
 * @Date Created in 2019/7/1 19:07
 */

@Service
public class UserForbiddenServiceImpl implements UserForbiddenService {

    private final String forbiddenURL = "/user/forbidden";
    private final String forbiddenAdminURL = "/admin/user/forbidden";

    @Autowired
    AccountLoginMapper accountLoginMapper;

    @Autowired
    AccountRegisterMapper accountRegisterMapper;

    @Autowired
    UserForbiddenMapper userForbiddenMapper;

    @Autowired
    DateUtil dateUtil;

    private BaseRsp innerAddUserForbidden(UserForbiddenAdminDTO adminDTO)
    {
        adminDTO.setOperator(getOperatorName());
        String url = UrlConstant.SERVER_URL + forbiddenURL + "/batch";
        String req = JSONObject.toJSONString(adminDTO);
        String body = HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);
        BaseRsp rsp = JSONObject.parseObject(body, BaseRsp.class);
        return rsp;
    }

    private void addRelativeDeviceId(UserForbiddenVO userForbiddenVO)
    {
        String endTime = dateUtil.getCurrentTime();
        String startTime = dateUtil.getDeltaDate(30, "yyyy-MM-dd HH:mm:ss");
        List<String> deviceIdList = new ArrayList();
        boolean flag = false;
        //找30天以内登录的设备
        if (userForbiddenVO.getIsLoginDevice()!= null && userForbiddenVO.getIsLoginDevice() ==1)
        {
            List<String> tableNameList = CommonUtil.getTableListFromDate(startTime,endTime, "account_login");
            List<String> loginDeviceIdList = accountLoginMapper.getDeviceIdByAccountId(tableNameList, startTime, endTime, userForbiddenVO.getUid());
            deviceIdList.addAll(loginDeviceIdList);
            flag = true;
        }
        //获取注册的deviceId
        if (userForbiddenVO.getIsRegisterDevice()!= null && userForbiddenVO.getIsRegisterDevice() ==1)
        {
            String deviceId = accountRegisterMapper.getDeviceIdByAccountId(userForbiddenVO.getUid());
            if (deviceId != null && !deviceIdList.contains(deviceId)){
                deviceIdList.add(deviceId);
            }
            flag = true;
        }
        if(flag && !deviceIdList.isEmpty()) {
            UserForbiddenAdminDTO userForbiddenAdminDTO = new UserForbiddenAdminDTO();
            userForbiddenAdminDTO.setStartTime(userForbiddenVO.getStartTime());
            userForbiddenAdminDTO.setEndTime(userForbiddenVO.getEndTime());
            userForbiddenAdminDTO.setExistLimitTime(userForbiddenVO.getExistLimitTime());
            userForbiddenAdminDTO.setForbiddenType((byte) 6);
            userForbiddenAdminDTO.setForbiddenValues(deviceIdList.toArray(new String[deviceIdList.size()]));
            userForbiddenAdminDTO.setReason(userForbiddenVO.getReason());
            innerAddUserForbidden(userForbiddenAdminDTO);
        }
    }


    @Override
    public void addUserForbidden(UserForbiddenVO userForbiddenVO) {
        userForbiddenVO.setOperator(getOperatorName());
        String url = UrlConstant.SERVER_URL + forbiddenURL;
        String req = JSONObject.toJSONString(userForbiddenVO);
        String body = HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);
        BaseRsp rsp = JSONObject.parseObject(body, BaseRsp.class);
        if (rsp == null || rsp.getStatus() != ResultEnum.SUCCESS.getState()) {
            throw new BusinessException(ResultEnum.FAILURE);
        }
        if (userForbiddenVO.getUid() != null && userForbiddenVO.getForbiddenType()==0) {
            addRelativeDeviceId(userForbiddenVO);
        }
    }

    @Override
    public void updateUserForbidden(UserForbiddenVO userForbiddenVO) {

        userForbiddenVO.setDeblockOperator(getOperatorName());
        userForbiddenVO.setState(userForbiddenVO.getState());
        String url = UrlConstant.SERVER_URL + forbiddenURL + "/" + userForbiddenVO.getForbiddenId();
        String req = JSONObject.toJSONString(userForbiddenVO);
        String body = HttpInvokeUtil.httpPutJson(url, req, UrlConstant.DefaultEncode, null);
        BaseRsp rsp = JSONObject.parseObject(body, BaseRsp.class);
        if (rsp == null || rsp.getStatus() != ResultEnum.SUCCESS.getState()) {
            throw new BusinessException(ResultEnum.FAILURE);
        }
    }

    @Override
    public void removeUserForbidden(String forbiddenId) {
        String url = UrlConstant.SERVER_URL + forbiddenURL + "/" + forbiddenId;
        Map<String, String> headMap = new HashMap<>();
        String body = HttpInvokeUtil.httpDelete(url, headMap);
        BaseRsp rsp = JSONObject.parseObject(body, BaseRsp.class);
        if (rsp == null || rsp.getStatus() != ResultEnum.SUCCESS.getState()) {
            throw new BusinessException(ResultEnum.FAILURE);
        }
    }

    @Override
    public Map<String, Object> listUserForbidden(Long uid, String forbiddenId, Byte forbiddenType, String forbiddenValue, Byte existLimitTime, Byte state, Integer offset, Integer limit, String startTime, String endTime) {
        String url = UrlConstant.SERVER_URL + forbiddenAdminURL;
        Map<String, String> paramMap = new HashMap<>();

        if (offset != null) {
            paramMap.put("offset", offset.toString());
        }
        if (limit != null) {
            paramMap.put("limit", limit.toString());
        }
        if (uid != null) {
            paramMap.put("uid", uid.toString());
        }
        if (forbiddenId != null) {
            paramMap.put("forbidden_id", forbiddenId);
        }
        if (forbiddenType != null) {
            paramMap.put("forbidden_type", forbiddenType.toString());
        }
        if (forbiddenValue != null) {
            paramMap.put("forbidden_value", forbiddenValue);
        }
        if (existLimitTime != null) {
            paramMap.put("exist_limit_time", existLimitTime.toString());
        }
        if (state != null) {
            paramMap.put("state", state.toString());
        }
        if (startTime != null) {
            paramMap.put("startTime", startTime);
        }
        if (endTime != null) {
            paramMap.put("endTime", endTime);
        }


        String body = HttpInvokeUtil.httpGet(url, paramMap, null);
        BaseRsp rsp = JSONObject.parseObject(body, BaseRsp.class);
        if (rsp == null || rsp.getStatus() != ResultEnum.SUCCESS.getState()
                || rsp.getData() == null) {
            throw new BusinessException(ResultEnum.FAILURE);
        }
        Map<String, Object> rspMap = (Map<String, Object>) rsp.getData();
        return rspMap;
    }

    @Override
    public BaseRsp batchAddUserForbidden(UserForbiddenAdminDTO adminDTO) {
        adminDTO.setOperator(getOperatorName());
        String url = UrlConstant.SERVER_URL + forbiddenURL + "/batch";
        String req = JSONObject.toJSONString(adminDTO);
        String body = HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);
        BaseRsp rsp = JSONObject.parseObject(body, BaseRsp.class);
        if (rsp == null || rsp.getStatus() != ResultEnum.SUCCESS.getState()) {
            return rsp;
        }
        //如果批量封的账号
        boolean flag = false;
        if (adminDTO.getForbiddenType() ==0 && adminDTO.getUids() != null)
        {
            String endTime = dateUtil.getCurrentTime();
            String startTime = dateUtil.getDeltaDate(30, "yyyy-MM-dd HH:mm:ss");
            List<String> deviceIdList = new ArrayList();
            //找30天以内登录的设备
            if (adminDTO.getIsLoginDevice() != null && adminDTO.getIsLoginDevice() == 1) {
                List<String> tableNameList = CommonUtil.getTableListFromDate(startTime, endTime, "account_login");
                List<String> loginDeviceIdList = accountLoginMapper.getDeviceIdByAccountIdList(tableNameList, startTime, endTime, adminDTO.getUids());
                deviceIdList.addAll(loginDeviceIdList);
                flag = true;
            }
            //获取注册的deviceId
            if (adminDTO.getIsRegisterDevice() != null && adminDTO.getIsRegisterDevice() == 1) {
                List<String> registerDeviceIdList = accountRegisterMapper.getDeviceIdByAccountIdList(adminDTO.getUids());
                deviceIdList.addAll(registerDeviceIdList);
                flag = true;
            }
            Set<String> staffsSet = new HashSet(deviceIdList);
            if (flag && !staffsSet.isEmpty()) {
                adminDTO.setForbiddenType((byte) 6);
                adminDTO.setUids(null);
                adminDTO.setForbiddenValues(staffsSet.toArray(new String[staffsSet.size()]));
                return innerAddUserForbidden(adminDTO);
            }
        }
        return rsp;

    }

    @Override
    public Set<String> findForbiddenIp(Set<String> ipList) {
        return userForbiddenMapper.findForbiddenIp(ipList);
    }

    @Override
    public Set<String> findForbiddenDeviceId(Set<String> deviceIdList) {
        return userForbiddenMapper.findForbiddenDeviceId(deviceIdList);
    }

    private String getOperatorName() {
        Subject subject = SecurityUtils.getSubject();
        UserInfo activeUser = (UserInfo) subject.getPrincipal();
        return activeUser.getUsername();
    }

}
